package com.unitd.frame.spring.helper;

import com.unitd.frame.spring.SpringInstanceFactory;
import org.springframework.core.env.*;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @desc Spring应用环境对象信息处理工具类
 * @filename EnvironmentHelper.java
 * @copyright www.unitd.com
 * @author Hudan
 * @version 1.0
 * @date 2016/10/14
 */
public class EnvironmentHelper {

	/** 当前Spring的应用环境对象 */
	private static Environment environment;

	/**
	 * @desc 初始化属性对象
	 */
	public static void init() {
		if (environment == null && SpringInstanceFactory.isInitialized()) {
			synchronized (EnvironmentHelper.class) {
				environment = SpringInstanceFactory.getInstance(Environment.class);
			}
		}
	}

	public static boolean containsProperty(String key) {
		init();
		return environment == null ? false : environment.containsProperty(key);
	}

	/**
	 * @desc 根据key从当前Spring的应用环境对象中取出相应的属性信息
	 * @param key 属性对象key
	 * @return String
	 */
	public static String getProperty(String key) {
		// 先判断是否已初始化属性对象,如果未初始化则先初始化,否则直接获取
		init();

		return environment == null ? null : environment.getProperty(key);
	}

	/**
	 * @desc 获取指定前缀的属性对象
	 * @param prefix 属性前缀
	 * @return Map
	 */
	public static Map<String, Object> getAllProperties(String prefix) {
		init();

		if (environment == null) return null;

		MutablePropertySources propertySources = ((ConfigurableEnvironment) environment).getPropertySources();
		Map<String, Object> properties = new LinkedHashMap<>();
		for (PropertySource<?> source : propertySources) {
			// 为了兼容SpringCloud2.x, 增加server.servlet的判断
			if (source.getName().startsWith("servlet") || source.getName().startsWith("system")
					|| source.getName().startsWith("servlet")) {
				continue;
			}
			if (source instanceof EnumerablePropertySource) {
				for (String name : ((EnumerablePropertySource<?>) source).getPropertyNames()) {
					boolean match = StringUtils.isEmpty(prefix);
					if (!match) {
						match = name.startsWith(prefix);
					}
					if (match) {
						Object value = source.getProperty(name);
						if (value != null) {
							properties.put(name, value);
						}
					}
				}
			}
		}
		return Collections.unmodifiableMap(properties);
	}
}
